package com.slipper.system.codeless.service;

import java.util.List;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import com.slipper.constants.Constants;
import com.slipper.exception.CommonException;
import com.slipper.util.BeanUtil;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;

import com.slipper.system.codeless.dao.MobilePageDao;
import com.slipper.system.codeless.bo.MobilePageBO;

import com.slipper.core.transaction.ReadTransactional;
import com.slipper.core.transaction.WriteTransactional;
import com.slipper.util.Tool;
import com.slipper.util.UUID;

@Service
@ReadTransactional
public class MobilePageService {
    @Resource
    private MobilePageDao mobilePageDao;
    
    public MobilePageBO queryBy(String id) {
        return mobilePageDao.queryBy(id);
    }
    
    public List<MobilePageBO> queryList(MobilePageBO bo) {
        return mobilePageDao.queryList(bo);
    }
    
    public PageInfo<MobilePageBO> queryPage(MobilePageBO bo) {
        PageHelper.startPage(bo.getPageNumber(), bo.getPageSize());
        return new PageInfo<>(mobilePageDao.queryList(bo));
    }
    
    @WriteTransactional
    public int save(MobilePageBO bo) {
        if (Tool.isBlank(bo.getParentId())) {
            bo.setParentId(Constants.ROOT_ID);
        }

        if (Tool.isNotBlank(bo.getId())) {
            bo.setUpdateTime(System.currentTimeMillis());
            return mobilePageDao.update(bo);
        } else {
            bo.setId(UUID.getUUID());
            bo.setUpdateTime(System.currentTimeMillis());
            bo.setCreateTime(System.currentTimeMillis());

            MobilePageBO qo = new MobilePageBO();
            qo.setParentId(Tool.isBlank(bo.getParentId()) ? Constants.ROOT_ID : bo.getParentId());
            List<MobilePageBO> pageList = mobilePageDao.queryList(qo);
            if (pageList.isEmpty()) {
                bo.setOrdinal(1);
            } else {
                bo.setOrdinal(pageList.getLast().getOrdinal() + 1);
            }
            return mobilePageDao.insert(bo);
        }
    }
    
    @WriteTransactional
    public int delete(MobilePageBO bo) {
        if (bo.getId() != null) {
            MobilePageBO qo = new MobilePageBO();
            qo.setParentId(bo.getId());
            if (!mobilePageDao.queryList(qo).isEmpty()) {
                throw new CommonException("有子目录/页面，不允许删除！");
            }
        }
        if (bo.getIds() != null) {
            for (String id : bo.getIds()) {
                MobilePageBO qo = new MobilePageBO();
                qo.setParentId(id);
                if (!mobilePageDao.queryList(qo).isEmpty()) {
                    throw new CommonException("有子目录/页面，不允许删除！");
                }
            }
        }
        return mobilePageDao.delete(bo);
    }

    @WriteTransactional
    public int updateName(MobilePageBO bo) {
        return mobilePageDao.updateName(bo);
    }

    @WriteTransactional
    public int copy(MobilePageBO bo) {
        if (Tool.isBlank(bo.getId())) return 0;

        MobilePageBO source = mobilePageDao.queryBy(bo.getId());
        MobilePageBO target = BeanUtil.copy(source, MobilePageBO.class);
        target.setId(Tool.getUUID());
        target.setName(source.getName() + "_复制");
        target.setOrdinal(source.getOrdinal() + 1);
        target.setUpdateTime(System.currentTimeMillis());
        target.setCreateTime(System.currentTimeMillis());
        mobilePageDao.insert(target);

        MobilePageBO qo = new MobilePageBO();
        qo.setParentId(source.getParentId());
        List<MobilePageBO> pageList = mobilePageDao.queryList(qo);
        int ordinal = target.getOrdinal() + 1;
        boolean start = false;
        for (MobilePageBO page : pageList) {
            if (start && !page.getId().equals(target.getId())) {
                page.setOrdinal(ordinal++);
                mobilePageDao.updateOrdinal(page);
            } else if (page.getId().equals(bo.getId())) {
                start = true;
            }
        }

        return 1;
    }

    @WriteTransactional
    public void saveList(List<MobilePageBO> list) {
        if (list == null) return;

        list.forEach(item -> {
            if (mobilePageDao.queryBy(item.getId()) != null) {
                item.setUpdateTime(System.currentTimeMillis());
                mobilePageDao.update(item);
            } else {
                item.setUpdateTime(System.currentTimeMillis());
                item.setCreateTime(System.currentTimeMillis());
                mobilePageDao.insert(item);
            }
        });
    }

    @WriteTransactional
    public int saveJsonList(List<MobilePageBO> pageList) {
        pageList.forEach(page -> mobilePageDao.updateJson(page));
        return 1;
    }

    @WriteTransactional
    public int updatePosition(MobilePageBO bo) {
        if (Tool.isBlank(bo.getParentId())) {
            bo.setParentId(Constants.ROOT_ID);
        }

        MobilePageBO qo = new MobilePageBO();
        qo.setParentId(Tool.isBlank(bo.getParentId()) ? Constants.ROOT_ID : bo.getParentId());
        List<MobilePageBO> pageList = mobilePageDao.queryList(qo);

        int i = 1;
        for (MobilePageBO page : pageList) {
            if (page.getId().equals(bo.getBeforeId())) {
                bo.setOrdinal(i++);
            }
            page.setOrdinal(i++);
            if (page.getId().equals(bo.getAfterId())) {
                bo.setOrdinal(i++);
            }
            mobilePageDao.updateOrdinal(page);
        }
        if (bo.getOrdinal() == null) {
            bo.setOrdinal(i);
        }
        mobilePageDao.updateOrdinal(bo);

        return 1;
    }
}
